//静态字段和静态方法

//实例字段在每个实例中都有自己的一个独立“空间”，!!!但是静态字段只有一个共享“空间”!!!，所有实例都会共享该字段。举个例子：

//有一种字段，是用static修饰的字段，称为静态字段：static field。
class Person {
	public String name;
	public int age;

	//定义静态field number
	public static int number;
}

// static field
public class Main {
	public static void main(String[] args) {
		Person ming = new Person("Xiao Ming",12);
		Person hong = new Person("Xiao Ming",15);

		ming.number = 88;
		System.out.println(hong.number);

		hong.number = 99;
		System.out.println(ming.number);
	}
}

class Person {
	public String name;
	public int age;

	public static int number;

	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
}

/*
对于静态字段，无论修改哪个实例的静态字段，效果都是一样的：所有实例的静态字段都被修改了，原因是静态字段并不属于实例：

        ┌──────────────────┐
ming ──>│Person instance   │
        ├──────────────────┤
        │name = "Xiao Ming"│
        │age = 12          │
        │number ───────────┼──┐    ┌─────────────┐
        └──────────────────┘  │    │Person class │
                              │    ├─────────────┤
                              ├───>│number = 99  │
        ┌──────────────────┐  │    └─────────────┘
hong ──>│Person instance   │  │
        ├──────────────────┤  │
        │name = "Xiao Hong"│  │
        │age = 15          │  │
        │number ───────────┼──┘
        └──────────────────┘
虽然实例可以访问静态字段，但是它们指向的其实都是Person class的静态字段。所以，所有实例共享一个静态字段。

因此，不推荐用'实例变量.静态字段'去访问'静态字段'，因为在Java程序中，实例对象并没有静态字段。
//在代码中，'实例对象能访问静态字段'只是因为[编译器]可以根据实例类型自动转换为'类名.静态字段'来访问静态对象。

推荐用[类名]来访问'static field静态字段'。可以把'静态字段'理解为描述class本身的字段（非实例字段）。对于上面的代码，更好的写法是：
*/
Person.number = 99; // Person是一个class名
System.out.println(Person.number);


//静态方法 static method
/*
有静态字段，就有静态方法。用static修饰的方法称为静态方法。

调用实例方法必须通过一个实例变量，而调用静态方法则不需要实例变量，通过类名就可以调用。静态方法类似其它编程语言的函数。例如：
*/
public class Main {
	public static void main(String[] args) {
		Person.setNumber(99);
		System.out.println(Person.number);
	}
}

class Person {
	public static int number; //static field

	public static void setNumber(int value) {
		number = value; 
		//static method只能访问Classd的static
	}
}

/*
因为静态方法属于class而不属于实例instance，因此，静态方法内部static method，无法访问this变量，也无法访问实例字段，它只能访问静态字段。

通过实例变量也可以调用静态方法，但这只是编译器自动帮我们把实例改写成类名而已。

通常情况下，通过实例变量访问静态字段和静态方法，会得到一个编译警告。

静态方法经常用于工具类。例如：

Arrays.sort()

Math.random()

静态方法也经常用于辅助方法。注意到Java程序的入口main()也是静态方法。
*/



/*	接口的静态字段(static field of Interface)

因为interface是一个纯抽象类，所以它不能定义[实例字段]。但是，interface是可以有[静态字段]的，并且在interface中[静态字段]必须为final类型：
*/
public interface Person {
	public static final int MALE = 1;
	public static final int FEMALE = 2;
}

//实际上，因为interface的字段只能是public static final类型，所以我们可以把这些修饰符都去掉，上述代码可以简写为：
public interface Person {
	//编译器自动加上public static final
	int MALE = 1;
	int FEMALE = 2
}
//编译器会自动把MALE和FEMALE变为public static final类型。(因为interface Person中已经定义过了MALE和FEMALE是public static final)


/*
小结
	1.静态字段属于所有实例“共享”的字段，实际上是属于class的字段；

	2.调用静态方法不需要实例，无法访问this，但可以访问静态字段和其他静态方法；

	3.静态方法常用于工具类和辅助方法。
*/













